<template>
  <div class="">
    <div class="left-tools">
      <!--<el-button type="primary" @click="cancelAdd" class="contract-btn">撤销</el-button>-->
      <el-button type="primary" @click="titleContent = '';titleDialog = true; editFlag = false" class="contract-btn">小标题</el-button>
      <el-button  type="warning" @click="content = ''; dialogVisible = true; editFlag = false; rowLevel = 1" class="contract-btn">段落</el-button>
      <draggable v-model="list" :move="onMove" :options="dragOptions" @start="dragStart" @end="isDragging=false">
        <p v-for="item in list" :id="item.type">{{item.type}}</p>
      </draggable>
    </div>
    <div class="right-content">
      <draggable class="right-layout" :options="dragOptions2" v-model="listContent" style="border: 1px solid red;min-height: 40px" @add="myAdd">
        <div v-for="(c, index) in listContent" v-if="typeof c === 'string'" class="content-char" :style="c.indexOf('lineClass') > -1 ? 'width:100%' : ''"  @contextmenu="showMenu(index)">
          <div v-html="c"></div>
          <vue-context-menu :contextMenuData="contextMenuData"
                            :transferIndex="transferIndex"
                            @addTitleData="addTitleData(index)"
                            @addData="addData(index)"
                            @editData="editData(index)"
                            @deleteData="deleteData(index)">
          </vue-context-menu>
        </div>
        <el-input v-else-if="c instanceof Object && c.type=== 'input'"  v-model="c.value" style="width: 250px"></el-input>
        <el-date-picker v-else-if="c instanceof Object && c.type=== 'date'"  v-model="c.value" type="date" placeholder="选择日期" :value-format="c.valueFormat"></el-date-picker>
      </draggable>

      <draggable class="right-layout":options="dragOptions2" v-model="listTable" style="border: 1px solid green;min-height: 40px" @add="myAdd">
        <div class="content-table-th" v-for="item in listTable">{{item}}</div>
      </draggable>

    </div>

    <el-dialog
      title="小标题"
      :visible.sync="titleDialog"
      width="30%">
      <el-input
        placeholder="请输入内容"
        v-model="titleContent">
      </el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="titleDialog = false">取 消</el-button>
        <el-button type="primary" v-if="!editFlag" @click="addTitle">确 定</el-button>
        <el-button type="primary" v-if="editFlag" @click="editTitle">确 定</el-button>
      </span>
    </el-dialog>

    <el-dialog
      title="段落"
      :visible.sync="dialogVisible"
      width="30%">
      <el-input v-model="rowLevel" style="margin-bottom: 16px"></el-input>
      <el-input
        type="textarea"
        :autosize="{ minRows: 2, maxRows: 4}"
        placeholder="请输入内容"
        v-model="content">
      </el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" v-if="!editFlag" @click="addRow">确 定</el-button>
        <el-button type="primary" v-if="editFlag" @click="editRow">确 定</el-button>
      </span>
    </el-dialog>

    <el-dialog
      title="段落"
      :visible.sync="addVisible"
      width="30%">
      <el-input v-model="rowLevel" style="margin-bottom: 16px"></el-input>
      <el-input
        type="textarea"
        :autosize="{ minRows: 2, maxRows: 4}"
        placeholder="请输入内容"
        v-model="content">
      </el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addVisible = false">取 消</el-button>
        <el-button type="primary" @click="insertRow">确 定</el-button>
      </span>
    </el-dialog>

    <el-dialog
      title="小标题"
      :visible.sync="addDialog"
      width="30%">
      <el-input
        placeholder="请输入内容"
        v-model="titleContent">
      </el-input>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addDialog = false">取 消</el-button>
        <el-button type="primary" @click="insertTitle">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
  import draggable from 'vuedraggable';
  export default {
    data() {
      return {
        list:[{
          type: 'input',
          value: ''
        },{
          type: 'date',
          valueFormat: 'yyyy-MM-dd',
          value: ''
        }],
        listContent: [],
        editable:true,
        isDragging: false,
        delayedDragging:false,
        controlHistory: [],
        controlMap:{},
        activeName: '',
        content: '',
        titleContent: '',
        editContent: '',
        dialogVisible: false,
        titleDialog: false,
        listTable:[],
        rowLevel: 1,
        editKey: '',
        addVisible:false,
        addDialog: false,
        transferIndex: null,
        editFlag: false,
        contextMenuData: {
          menuName: 'demo',
          axios: {
            x: null,
            y: null
          },
          menulists: [
            {
              fnHandler: 'addTitleData',
              btnName: '插入标题'
            },
            {
              fnHandler: 'addData',
              btnName: '插入段落'
            },
            {
              fnHandler: 'editData', // Binding events(绑定事件)
              btnName: '编辑' // The name of the menu option (菜单名称)
            },
            {
              fnHandler: 'deleteData',
              btnName: '删除'
            }
          ]
        }
      };
    },
    created(){
    },
    components:{
      draggable
    },
    methods:{
      onMove ({relatedContext, draggedContext}) {
        // const relatedElement = relatedContext.element;
        // const draggedElement = draggedContext.element;
        return relatedContext.list;
      },
      addTitle(){
        //let title = '一、产品名称、商标、型号、厂家、数量、金额、供货时间及数';
        let title = this.titleContent;
        this.listContent.push('<p class="lineClass"><b>' + title + '</b><br></p>');
        let his = {
          start: this.listContent.length - 1,
          len: 1,
          content: title,
//          hisIndex: this.controlHistory.length,
          type: 'title'
        };
//        this.controlHistory.push(his);
        this.controlMap['title_' + his.start + '_' + his.len] = his;
        this.titleDialog = false;
      },
      addRow(){
        // let row = '应当符合国家强制性质量标准和产品明示的质量标准，同时应当符合附件一所列之技术标准，供方随货提供需方该批产品的质量报告单、产品合格证和送货单。否则需方有权直接拒收。同时每批到货需提供海关商检报告或每年一次需提供第三方型式检验报告（须含农残检验项目）。产品应符合其行业用途及使用期限。应当符合国家强制性质量标准和产品明示的质量标准，同时应当符合附件一所列之技术标准，供方随货提供需方该批产品的质量报告单、产品合格证和送货单。否则需方有权直接拒收。同时每批到货需提供海关商检报告或每年一次需提供第三方型式检验报告（须含农残检验项目）。产品应符合其行业用途及使用期限。';
        let row = this.content;
        this.listContent.push('<div class="lineClass"></div>');
        this.listContent.push('<div style="width: '+ 40 * this.rowLevel +'px"></div>');
        for (let i in row) {
          this.listContent.push(row[i]);
        }
        let his = {
          start: this.listContent.length - row.length - 2,
          len: row.length + 2,
          content: row,
          rowLevel: this.rowLevel,
//          hisIndex: this.controlHistory.length,
          type: 'content'
        };
//        this.controlHistory.push(his);
        this.controlMap['content_' + his.start + '_' + his.len] = his;
        this.dialogVisible = false
      },
      cancelAdd(){
//        let t = this.controlHistory.pop();
//        this.listContent.splice(t.start, t.len);
      },
      dragStart(evt){
        this.activeName = evt.item.id;
        this.isDragging=true;
      },
      myAdd(evt){
        let his = {
          start: evt.newIndex,
          len: 1,
          content: {
            type: 'input',
            value: ''
          },
//          hisIndex: this.controlHistory.length,
          type: 'input'
        };

//        this.controlHistory.push(his);
        let key = this.searchMap(evt.newIndex);
        this.iteratorKey(key, this.controlMap[key].len + 1, this.controlMap[key].len);
        this.controlMap[key].len += 1;
      },
      showMenu (index) {
        this.transferIndex = index;
        event.preventDefault();
        let x = event.clientX;
        let y = event.clientY;
        // Get the current location
        this.contextMenuData.axios = {
          x, y
        }
      },
      addData(e){
        this.editKey = this.searchMap(e);
        this.rowLevel = 1;
        this.content = '';
        this.addVisible = true;
      },
      insertRow(){
        let row = this.content;
        let data = JSON.parse(JSON.stringify(this.controlMap[this.editKey]));
        let start = data.start * 1 + data.len * 1;
        this.listContent.splice(start, 0, '<div class="lineClass"></div>')
        this.listContent.splice(start + 1, 0, '<div style="width: '+ 40 * this.rowLevel +'px"></div>')
        for (let i in row) {
          this.listContent.splice(start + 2 + i*1, 0, row[i]);
        }
        let his = {
          start: start,
          len: row.length + 2,
          content: row,
          rowLevel: this.rowLevel,
//          hisIndex: this.controlHistory.length,
          type: 'content'
        };
//        this.controlHistory.push(his);
        this.iteratorKey('content_' + his.start + '_' + his.len, his.len, 0);
        this.controlMap['content_' + his.start + '_' + his.len] = his;
        this.addVisible = false;
      },
      addTitleData(e){
        this.editKey = this.searchMap(e);
        this.titleContent = '';
        this.addDialog = true;
      },
      insertTitle(){
        let data = JSON.parse(JSON.stringify(this.controlMap[this.editKey]));
        let start = data.start * 1 + data.len * 1;
        let title = this.titleContent;
        this.listContent.splice(start, 0 ,'<p class="lineClass"><b>' + title + '</b><br></p>');
        let his = {
          start: start,
          len: 1,
          content: title,
//          hisIndex: this.controlHistory.length,
          type: 'title'
        };
//        this.controlHistory.push(his);
        this.iteratorKey('title_' + his.start + '_' + his.len, his.len, 0);
        this.controlMap['title_' + his.start + '_' + his.len] = his;
        this.addDialog = false;
      },
      editData (e) {
        this.editKey = '';
        let key =this.searchMap(e);
        let data = this.controlMap[key];
        if (key.indexOf('content') === 0) {
          this.dialogVisible = true;
          this.editFlag = true;
          this.rowLevel = data.rowLevel;
          this.content = data.content;
          this.editKey = key;
        }
        if (key.indexOf('title') === 0) {
          this.titleDialog = true;
          this.editFlag = true;
          this.titleContent = data.content;
          this.editKey = key;
        }
      },
      editTitle(){
        let title = this.titleContent;
        let data = this.controlMap[this.editKey];

        this.listContent.splice(data.start, 1 ,'<p class="lineClass"><b>' + title + '</b><br></p>');
//        this.controlHistory[data.hisIndex].content = title;
        this.controlMap[this.editKey].content = title;
        this.titleDialog = false;
      },
      editRow(){
        let content = this.content;
        let data = this.controlMap[this.editKey];

        this.listContent.splice(data.start, data.len);
        this.listContent.splice(data.start, 0, '<div class="lineClass"></div>')
        this.listContent.splice(data.start*1 + 1, 0, '<div style="width: '+ 40 * this.rowLevel +'px"></div>')
        for (let i in content) {
          this.listContent.splice(data.start*1 + 2 + i*1, 0, content[i]);
        }
        let postion = this.editKey.split('_');
        let tempIndex = postion[1];
        let newLength = content.length + 2;
        this.controlMap[postion[0] + '_' + tempIndex + '_' + newLength] = JSON.parse(JSON.stringify(data));
        this.controlMap[postion[0] + '_' + tempIndex + '_' + newLength].len = newLength;
        this.controlMap[postion[0] + '_' + tempIndex + '_' + newLength].content = content;
//        this.controlHistory[data.hisIndex] = JSON.parse(JSON.stringify(this.controlMap[postion[0] + '_' + tempIndex + '_' + newLength]));
        delete this.controlMap[this.editKey];
        this.iteratorKey(this.editKey, newLength, data.len);
        this.dialogVisible = false;
      },
      iteratorKey(key, newLength, oldLength){
        let arr =  Object.keys(this.controlMap);
        let postion = key.split('_');
        let tempIndex = postion[1];
        for (let i in arr) {
          let pos = arr[i].split("_");
          if (pos[1] >= tempIndex*1 + oldLength) {
            let newKey = pos[0] + "_" + (pos[1]*1 + (newLength*1 - oldLength*1)) + '_' + this.controlMap[arr[i]].len;
            this.controlMap[newKey] = JSON.parse(JSON.stringify(this.controlMap[arr[i]]));
            this.controlMap[newKey].start = pos[1]*1 + (newLength*1 - oldLength*1);
            delete this.controlMap[arr[i]];
          }
        }
      },
      deleteData (e) {
        let key = this.searchMap(e);
        let childList = this.searchChild(key);
        if (childList && childList.length > 0) {
          for (let i=0; i < childList.length; i++) {
              this.deleteBykey(childList[i].type + "_" + childList[i].start + "_" + childList[i].len);
          }
        }
        this.deleteBykey(key);
      },
      deleteBykey(key){
        let data = this.controlMap[key];
        this.listContent.splice(data.start, data.len);
//        this.controlHistory.splice(data.hisIndex, 1);
        delete this.controlMap[key];
        this.iteratorKey(key, 0, data.len);
      },
      searchMap(index){
        let arr =  Object.keys(this.controlMap);
        for (let i in arr) {
          let pos = arr[i].split("_");
          if (pos[1] <= index && (pos[1] * 1 + pos[2] * 1) > index) {
              return arr[i];
          }
        }
      },
      searchChild(key){
        let data = this.controlMap[key];
        let index = key.split('_')[1] * 1;
        let result = [];
        let arr = Object.values(this.controlMap).sort((a, b)=> {
          return a.start - b.start;
        });
        for (let i=0; i < arr.length; i++) {
          if (arr[i].start > index && arr[i].rowLevel && (arr[i].rowLevel > data.rowLevel || !data.rowLevel)) {
            result.push(arr[i])
          } else if (arr[i].start > index) {
            break;
          } else {
            continue;
          }
        }
        return result.reverse();
      }
    },
    computed: {
      dragOptions () {
        return  {
          animation: 0,
          group: {
            name: 'description',
            pull: 'clone'
          },
          disabled: !this.editable,
          ghostClass: 'ghost',
          sort: false
        };
      },
      dragOptions2 () {
        return  {
          animation: 0,
          group: {
            name: 'description'
          },
          disabled: !this.isDragging,
          ghostClass: 'ghost'
        };
      }
    },
    watch: {
      isDragging (newValue) {
        if (newValue){
          this.delayedDragging= true
          return
        }
        this.$nextTick( () =>{
          this.delayedDragging =false
        })
      }
    }
  }
</script>

<style scoped>
  .left-tools {
    width: 300px;
    border-right: 1px solid #d1dbe5;
    position: absolute;
    top: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    padding: 16px;
  }

  .contract-btn{
    margin: 10px 0;
    width: 100px;
  }

  .right-content {
    width: calc(100% - 300px);
    position: absolute;
    top: 0;
    left: 300px;
    bottom: 0;
    right: 0;
  }

  .right-content .right-layout{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
  }

  .right-content .right-layout .content-char{
    line-height: 45px;
  }

  .right-content .right-layout .content-table-th{
    padding: 8px;
    border: 1px solid blue;
    border-right: none;
    flex-grow: 1;
  }

  .right-content .right-layout .content-table-th{
    padding: 8px;
    border: 1px solid blue;
    border-right: none;
  }

  .right-content .right-layout .content-table-th:last-child{
    border-right: 1px solid blue;
  }
</style>
